﻿using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.Animations;

public class SplitModelAnim
{
    static string bVlaue = "ValidLock";
    static string aniKey = "Action";

    #region 樹木
    [MenuItem("Assets/模型/分割采集樹木模型动画")]
    public static void SplitTreeModelAnimations()
    {
        string filepath = AssetDatabase.GetAssetPath(Selection.activeObject);
        string fileName = Path.GetFileNameWithoutExtension(filepath);
        Debug.Log("fileName = " + fileName);
        string txtPath = filepath.Replace("FBX", "txt");
        TextAsset binAsset = (TextAsset)AssetDatabase.LoadAssetAtPath<TextAsset>(filepath.Replace("FBX", "csv"));
        Debug.Log("txt = " + binAsset.ToString());
        ModelImporter importer = AssetImporter.GetAtPath(filepath) as ModelImporter;
        List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>(importer.clipAnimations);
        Dictionary<string, ModelImporterClipAnimation> dic = new Dictionary<string, ModelImporterClipAnimation>();
        foreach (ModelImporterClipAnimation clip in clips)
        {
            dic.Add(clip.name, clip);
        }
        string[] lineArray = binAsset.text.Replace("\r", "").Split('\n');
        List<ModelImporterClipAnimation> addClip = new List<ModelImporterClipAnimation>();
        string[] strArr = filepath.Split('/');
        string controllerName = strArr[strArr.Length - 2] + "AnimCtrl.controller";
        string controllerPath = Path.GetDirectoryName(filepath) + "/" + controllerName;
        AnimatorController animatorController = null;
        Debug.Log("controllerName =" + controllerName);
        Debug.Log("controllerPath =" + controllerPath);
        if (File.Exists(controllerPath))
        {
            animatorController = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>(controllerPath);
        }
        else
        {
            animatorController = AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
            animatorController.AddParameter(bVlaue, AnimatorControllerParameterType.Bool);
            animatorController.AddParameter(aniKey, AnimatorControllerParameterType.Int);
        }

        AnimatorControllerLayer layer = animatorController.layers[0];
        AnimatorStateMachine sm = layer.stateMachine;
        for (int i = 1; i < lineArray.Length; i++)
        {
            Debug.Log("lineArray[i] =" + lineArray[i]);
            if (string.IsNullOrEmpty(lineArray[i])) continue;
            string[] arr = lineArray[i].Split(',');
            ModelImporterClipAnimation clip;
            if (dic.TryGetValue(arr[0], out clip))
            {
                clip = dic[arr[0]];
            }
            else
            {
                clip = new ModelImporterClipAnimation();
                addClip.Add(clip);
            }
            clip.name = arr[0];
            clip.firstFrame = float.Parse(arr[1]);
            clip.lastFrame = float.Parse(arr[2]);
            clip.loopTime = int.Parse(arr[4]) == 0;
        }
        clips.AddRange(addClip);
        importer.clipAnimations = clips.ToArray();
        importer.SaveAndReimport();
        AddAnimationState(sm, filepath, lineArray);
    }

    #endregion

    #region 主角
    [MenuItem("Assets/模型/分割主角模型动画")]
    public static void SplitModelAnimations()
    {
        string filepath = AssetDatabase.GetAssetPath(Selection.activeObject);
        string fileName = Path.GetFileNameWithoutExtension(filepath);
        Debug.Log("fileName = " + fileName);
        string txtPath = filepath.Replace("FBX", "txt");
        TextAsset binAsset = (TextAsset)AssetDatabase.LoadAssetAtPath<TextAsset>(filepath.Replace("FBX", "csv"));
        Debug.Log("txt = " + binAsset.ToString());
        ModelImporter importer = AssetImporter.GetAtPath(filepath) as ModelImporter;
        List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>(importer.clipAnimations);
        Dictionary<string, ModelImporterClipAnimation> dic = new Dictionary<string, ModelImporterClipAnimation>();
        foreach (ModelImporterClipAnimation clip in clips)
        {
            dic.Add(clip.name, clip);
        }
        string[] lineArray = binAsset.text.Replace("\r", "").Split('\n');
        List<ModelImporterClipAnimation> addClip = new List<ModelImporterClipAnimation>();
        string[] strArr = filepath.Split('/');
        string controllerName = strArr[strArr.Length - 2] + "AnimCtrl.controller";
        string controllerPath = Path.GetDirectoryName(filepath) + "/"+ controllerName;
        AnimatorController animatorController = null;
        Debug.Log("controllerName =" + controllerName);
        Debug.Log("controllerPath =" + controllerPath);
        if (File.Exists(controllerPath))
        {
            animatorController = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>(controllerPath);
        }
        else
        {
            animatorController = AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
            animatorController.AddParameter(bVlaue, AnimatorControllerParameterType.Bool);
            animatorController.AddParameter(aniKey, AnimatorControllerParameterType.Int);
        }

        AnimatorControllerLayer layer = animatorController.layers[0];
        AnimatorStateMachine sm = layer.stateMachine;
        for (int i = 1; i < lineArray.Length; i++)
        {
            Debug.Log("lineArray[i] =" + lineArray[i]);
            if (string.IsNullOrEmpty(lineArray[i])) continue;
            string[] arr = lineArray[i].Split(',');
            ModelImporterClipAnimation clip;
            if (dic.TryGetValue(arr[0], out clip))
            {
                clip = dic[arr[0]];
            }
            else
            {
                clip = new ModelImporterClipAnimation();
                addClip.Add(clip);
            }
            clip.name = arr[0];
            clip.firstFrame = float.Parse(arr[1]);
            clip.lastFrame = float.Parse(arr[2]);
            clip.loopTime = int.Parse(arr[4]) == 0;
        }
        clips.AddRange(addClip);
        importer.clipAnimations = clips.ToArray();
        importer.SaveAndReimport();
        AddAnimationState(sm, filepath, lineArray);
    }


    public static void AddAnimationState(AnimatorStateMachine _stateMachine, string filePath, string[] lineArray)
    {
        var _datas = AssetDatabase.LoadAllAssetsAtPath(filePath);
        Dictionary<string, AnimationClip> dic = new Dictionary<string, AnimationClip>();
        foreach (var _data in _datas)
        {
            if (!(_data is AnimationClip))
            {
                continue;
            }
            AnimationClip _newClip = _data as AnimationClip;
            Debug.Log("clip = " + _newClip.name);
            dic.Add(_newClip.name, _newClip);
        }
        for (int i = 1; i < lineArray.Length; i++)
        {
            if (string.IsNullOrEmpty(lineArray[i])) continue;
            string[] arr = lineArray[i].Split(',');
            string name = arr[0];
            int condision = int.Parse(arr[3]);
            foreach (ChildAnimatorState st in _stateMachine.states)
            {
                if (st.state.name == name)
                {
                    _stateMachine.RemoveState(st.state);
                    break;
                }
            }
            AnimatorState state = _stateMachine.AddState(name);
            state.motion = dic[name];
            state.writeDefaultValues = true;
            AnimatorStateTransition transition = _stateMachine.AddAnyStateTransition(state);
            transition.duration = float.Parse(arr[5]);
            transition.AddCondition(AnimatorConditionMode.If, 0, bVlaue);
            transition.AddCondition(AnimatorConditionMode.Equals, condision, aniKey);
        }
    }
    #endregion

    #region 主角表情
    [MenuItem("Assets/模型/分割表情模型动画")]
    public static void SplitModelEmotion()
    {
        string filepath = AssetDatabase.GetAssetPath(Selection.activeObject);
        string fileName = Path.GetFileNameWithoutExtension(filepath);
        string clipDir = filepath.Replace(Path.GetFileName(filepath), "");
        Debug.Log("fileName = " + fileName);

        AnimatorController ctrl = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>(filepath);  
        if (ctrl == null) 
        {
            Debug.LogError("选择的文件错误(应选.controller):" + filepath);
            return;
        }


        // 获取文本数据
        TextAsset binAsset = (TextAsset)AssetDatabase.LoadAssetAtPath<TextAsset>(filepath.Replace(".controller", ".csv"));
        string[] lineArray = binAsset.text.Replace("\r", "").Split('\n');
        List<string> clipNameList = new List<string>();
        for (int i = 1; i < lineArray.Length; i++)
        {
            Debug.Log("lineArray[i] =" + lineArray[i]);
            string[] arr = lineArray[i].Split(',');
            int transitionId =int.Parse(arr[0]);
            string clipName = arr[1];
            bool isDefault = int.Parse(arr[2]) == 1;
            string clipFilePath = clipDir + clipName + ".anim";
            //加载对象
            //Debug.Log("clipFilePaht:"+clipFilePath);
            AnimationClip clip = (AnimationClip)AssetDatabase.LoadAssetAtPath<AnimationClip>(clipFilePath);
            if (clip == null) 
            {
                Debug.Log("找不到动画片段--》:"+ clipFilePath);
                continue;
            }


            AnimatorControllerLayer layer = ctrl.layers[0];
            AnimatorStateMachine sm = layer.stateMachine;
            //移除片段
            foreach (ChildAnimatorState st in sm.states)
            {
                if (st.state.name == clipName)
                {
                    //Debug.LogWarning("匹配到相同片段:" + st.state.name);
                    sm.RemoveState(st.state);
                    break;
                }
            }
            AnimatorState state = sm.AddState(clip.name);
            //设置片段
            state.motion = clip;
            state.writeDefaultValues = true;
            if (isDefault)
            {
                sm.defaultState = state;
            }

            AnimatorStateTransition transition = sm.AddAnyStateTransition(state);
            transition.duration = 0;
            transition.interruptionSource = TransitionInterruptionSource.Source;
            transition.canTransitionToSelf = false;
            transition.AddCondition(AnimatorConditionMode.Equals, transitionId, aniKey);

        }
    }



    #endregion

    #region 恐龙
    [MenuItem("Assets/模型/分割恐龙模型动画")]
    public static void SplitDinosaurModelAnimations()
    {
        string filepath = AssetDatabase.GetAssetPath(Selection.activeObject);
        string fileName = Path.GetFileNameWithoutExtension(filepath);
        Debug.Log("fileName = " + fileName);
        string txtPath = filepath.Replace("FBX", "txt");
        TextAsset binAsset = (TextAsset)AssetDatabase.LoadAssetAtPath<TextAsset>(filepath.Replace("FBX", "csv"));
        Debug.Log("txt = " + binAsset.ToString());
        ModelImporter importer = AssetImporter.GetAtPath(filepath) as ModelImporter;
        List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>(importer.clipAnimations);
        Dictionary<string, ModelImporterClipAnimation> dic = new Dictionary<string, ModelImporterClipAnimation>();
        foreach (ModelImporterClipAnimation clip in clips)
        {
            dic.Add(clip.name, clip);
        }
        string[] lineArray = binAsset.text.Replace("\r", "").Split('\n');
        List<ModelImporterClipAnimation> addClip = new List<ModelImporterClipAnimation>();
        string[] strArr = filepath.Split('/');
        //string controllerName = strArr[strArr.Length - 2] + "_AnimCtrl.controller";
        string controllerName = fileName + "_AnimCtrl.controller";
        string controllerPath = Path.GetDirectoryName(filepath) + "/" + controllerName;
        AnimatorController animatorController = null;
        Debug.Log("controllerName =" + controllerName);
        Debug.Log("controllerPath =" + controllerPath);
        if (File.Exists(controllerPath))
        {
            animatorController = (AnimatorController)AssetDatabase.LoadAssetAtPath<AnimatorController>(controllerPath);
        }
        else
        {
            animatorController = AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
            animatorController.AddParameter(bVlaue, AnimatorControllerParameterType.Bool);
            animatorController.AddParameter(aniKey, AnimatorControllerParameterType.Int);
        }

        AnimatorControllerLayer layer = animatorController.layers[0];
        AnimatorStateMachine sm = layer.stateMachine;
        for (int i = 1; i < lineArray.Length; i++)
        {
            Debug.Log("lineArray[i] =" + lineArray[i]);
            if (string.IsNullOrEmpty(lineArray[i])) continue;
            string[] arr = lineArray[i].Split(',');
            ModelImporterClipAnimation clip;
            if (dic.TryGetValue(arr[0], out clip))
            {
                clip = dic[arr[0]];
            }
            else
            {
                clip = new ModelImporterClipAnimation();
                addClip.Add(clip);
            }
            clip.name = arr[0];
            clip.firstFrame = float.Parse(arr[1]);
            clip.lastFrame = float.Parse(arr[2]);
            clip.loopTime = int.Parse(arr[4]) == 0;
        }
        clips.AddRange(addClip);
        importer.clipAnimations = clips.ToArray();
        importer.animationCompression = ModelImporterAnimationCompression.Off;
        importer.SaveAndReimport();
        AddDinosaurAnimationState(sm, filepath, lineArray);
    }



    public static void AddDinosaurAnimationState(AnimatorStateMachine _stateMachine, string filePath, string[] lineArray)
    {
        var _datas = AssetDatabase.LoadAllAssetsAtPath(filePath);
        Dictionary<string, AnimationClip> dic = new Dictionary<string, AnimationClip>();
        foreach (var _data in _datas)
        {
            if (!(_data is AnimationClip))
            {
                continue;
            }
            AnimationClip _newClip = _data as AnimationClip;
            Debug.Log("clip = " + _newClip.name);
            dic.Add(_newClip.name, _newClip);
        }
        for (int i = 1; i < lineArray.Length; i++)
        {
            if (string.IsNullOrEmpty(lineArray[i])) continue;
            string[] arr = lineArray[i].Split(',');
            string name = arr[0];
            int condision = int.Parse(arr[3]);
            foreach (ChildAnimatorState st in _stateMachine.states)
            {
                if (st.state.name == name)
                {
                    _stateMachine.RemoveState(st.state);
                    break;
                }
            }
            AnimatorState state = _stateMachine.AddState(name);
            state.motion = dic[name];
            state.writeDefaultValues = true;
            AnimatorStateTransition transition = _stateMachine.AddAnyStateTransition(state);
            transition.AddCondition(AnimatorConditionMode.If, 0, bVlaue);
            transition.AddCondition(AnimatorConditionMode.Equals, condision, aniKey);
        }
    }
    #endregion 
    [MenuItem("Assets/模型/生成鱼类预设")]
    public static void CreateFishModel()
    {
        string filepath = AssetDatabase.GetAssetPath(Selection.activeObject);
        string fileName = Path.GetFileName(filepath);
        Debug.Log("filepath = " + filepath);
        string txtPath = filepath.Replace("FBX", "txt");
        TextAsset binAsset = (TextAsset)AssetDatabase.LoadAssetAtPath<TextAsset>(filepath.Replace("FBX", "csv"));
        Debug.Log("txt = " + binAsset.ToString());
        ModelImporter importer = AssetImporter.GetAtPath(filepath) as ModelImporter;
        importer.animationType = ModelImporterAnimationType.Legacy;
        List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>(importer.clipAnimations);
        Dictionary<string, ModelImporterClipAnimation> dic = new Dictionary<string, ModelImporterClipAnimation>();
        foreach (ModelImporterClipAnimation clip in clips)
        {
            Debug.Log("clip.name =" + clip.name);
            dic.Add(clip.name, clip);
        }
        string[] lineArray = binAsset.text.Replace("\r", "").Split('\n');
        List<ModelImporterClipAnimation> addClip = new List<ModelImporterClipAnimation>();
        string[] strArr = filepath.Split('/');
        for (int i = 1; i < lineArray.Length; i++)
        {
            Debug.Log("lineArray[i] =" + lineArray[i]);
            if (string.IsNullOrEmpty(lineArray[i])) continue;
            string[] arr = lineArray[i].Split(',');
            ModelImporterClipAnimation clip;
            if (dic.TryGetValue(arr[0], out clip))
            {
                clip = dic[arr[0]];
            }
            else
            {
                clip = new ModelImporterClipAnimation();
                addClip.Add(clip);
            }
            clip.name = arr[0];
            clip.firstFrame = float.Parse(arr[1]);
            clip.lastFrame = float.Parse(arr[2]);
            clip.loopTime = int.Parse(arr[3]) == 0; 
        }
        clips.AddRange(addClip);
        importer.clipAnimations = clips.ToArray();
        importer.SaveAndReimport();
        GameObject cloneObj = GameObject.Instantiate<GameObject>(Selection.activeGameObject);
        Animation ani = cloneObj.GetComponent<Animation>();
        if(ani == null)
        {
            ani = cloneObj.AddComponent<Animation>();
        }
        cloneObj.name = cloneObj.name.Replace("(Clone)", "");
        Debug.Log("filepath =" + filepath);
        var _datas = AssetDatabase.LoadAllAssetsAtPath(filepath);
        for(int i = 0;i < _datas.Length;i++)
        {
            var _data = _datas[i];
            if (!(_data is AnimationClip))
            {
                continue;
            }
            AnimationClip _newClip = _data as AnimationClip;
            if(!_newClip.name.Contains("__"))
            {
                _newClip.legacy = true;
                Debug.LogError("clip = " + _newClip.name);
                ani.AddClip(_newClip, _newClip.name);
            }
            if (i == 0)
            {
                ani.clip = _newClip;
            }

        }
        if (cloneObj.GetComponent<Animator>()!= null)
        {
            GameObject.DestroyImmediate(cloneObj.GetComponent<Animator>());
        }
        ani.wrapMode = WrapMode.Loop;
        GameObject fish = new GameObject();
        fish.name = cloneObj.name;
        cloneObj.transform.SetParent(fish.transform);
        GameObject foodpoint = new GameObject();
        foodpoint.name = "foodpoint";
        foodpoint.transform.parent = fish.transform;
        foodpoint.transform.localPosition = Vector3.zero;
        foodpoint.transform.localScale = Vector3.one;
        GameObject centerpoint = new GameObject();
        centerpoint.name = "centerpoint";
        centerpoint.transform.parent = fish.transform;
        centerpoint.transform.localPosition = Vector3.zero;
        centerpoint.transform.localScale = Vector3.one;
        LODGroup lod = fish.AddComponent<LODGroup>();
        string materialPath = Path.GetDirectoryName(filepath) + "/Materials/Mat_" + fish.name + ".mat";
        Debug.Log("materialPath =" + materialPath);
        Material mat = (Material)AssetDatabase.LoadAssetAtPath<Material>(materialPath);
        GameObject obj1 = cloneObj.transform.Find(cloneObj.name).gameObject;
        LOD lod1 = new LOD(0.2f, new Renderer[] { obj1.GetComponent<SkinnedMeshRenderer>() });
        obj1.GetComponent<SkinnedMeshRenderer>().material = mat;
        if (cloneObj.transform.Find(cloneObj.name + "_scene") != null)
        {
            GameObject obj2 = cloneObj.transform.Find(cloneObj.name + "_scene").gameObject;
            LOD lod2 = new LOD(0.05f, new Renderer[] { obj2.GetComponent<SkinnedMeshRenderer>() });
            obj2.GetComponent<SkinnedMeshRenderer>().material = mat;
            lod.SetLODs(new LOD[] { lod1, lod2 });
        }
        fish.AddComponent<BoxCollider>();
        string path = filepath.Replace("FBX", "prefab");
        path = path.Replace("Asset", "Res");
        Object prefabObj = PrefabUtility.CreateEmptyPrefab(path);
        GameObject prefab = PrefabUtility.ReplacePrefab(fish, prefabObj);
        GameObject.DestroyImmediate(fish);
        AssetDatabase.SaveAssets();
    }

}
